/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2018-2020. All rights reserved.
 * Description: dynamic load helper implementation
 */
#include "cloud_service_loader.h"
#include <dlfcn.h>
#include "framework/infra/log/log.h"

namespace hiai {
CloudServiceLoader::CloudServiceLoader() : handle_(nullptr)
{
}

CloudServiceLoader::~CloudServiceLoader() //lint !e1540
{
    Deinit();
}

bool CloudServiceLoader::Init(const char* libName)
{
    std::lock_guard<std::mutex> lock(funcMapMutex_);
    if (handle_ != nullptr) {
        FMK_LOGW("alread loaded.");
        return false;
    }

    if (libName == nullptr) {
        FMK_LOGW("libname is empty.");
        return false;
    }

    handle_ = dlopen(libName, RTLD_LAZY);
    if (handle_ == nullptr) {
        FMK_LOGW("load lib failed,errmsg [%s]", dlerror());
        return false;
    }
    return true;
}

void CloudServiceLoader::Deinit()
{
    std::lock_guard<std::mutex> lock(funcMapMutex_);
    if (handle_ == nullptr) {
        FMK_LOGW("file not loaded.");
        return;
    }

    if (dlclose(handle_)) {
        FMK_LOGE("dlclose failed, errmsg[%s]", dlerror());
    }
    handle_ = nullptr;
}

bool CloudServiceLoader::IsValid() //lint !e1762
{
    return handle_ != nullptr;
}

void* CloudServiceLoader::GetSymbol(const char* symbol)
{
    std::lock_guard<std::mutex> lock(funcMapMutex_);
    if (handle_ == nullptr) {
        FMK_LOGE("file not loaded.");
        return nullptr;
    }

    auto it = funcMap_.find(symbol);
    if (it != funcMap_.end()) {
        return it->second;
    }
    auto funcPtr = dlsym(handle_, const_cast<char*>(symbol));
    if (funcPtr == nullptr) {
        FMK_LOGW("dlsym failed,errmsg [%s]", dlerror());
    }
    funcMap_[symbol] = funcPtr;
    return funcPtr;
}
} // namespace hiai
